/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.tabbedproperties.section;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.runtime.Assert;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.uml.Extend;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Relationship;

import com.cea.papyrus.core.commands.factories.DiagramElementDeleteCommandFactory;
import com.cea.papyrus.core.editor.CommandStackUtils;
import com.cea.papyrus.core.editor.MultiDiagramEditor;
import com.cea.papyrus.core.tabbedproperties.PropertyViewSection;
import com.cea.papyrus.diagram.usecase.command.ExtendConditionDisplayCreateCommand;
import com.cea.papyrus.diagram.usecase.helper.EdgeExtendHelper;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Property;

/**
 * Defines the appearance extend condition section of extends.
 * 
 * @author Gilles Cannenterre
 * @since 11 d�c. 06
 */
public class ExtendConditionPresentationSection extends PropertyViewSection {

	/**
	 * The check box show condition.
	 */
	private Button checkBoxShowCondition;
	
	/**
	 * The check box show condition.
	 */
	private Button checkBoxShowName;
		
	/** The current name appearance. */
	private boolean currentNameAppearance;
	
	/**
	 * The show condition selection listener.
	 */
	private SelectionListener showCondition;
		
	/**
	 * The show condition selection listener.
	 */
	private SelectionListener showName;

	/** The current extend condition appearance. */
	private boolean currentExtendConditionAppearance;
	
	/**
	 * Creates the controls.
	 * 
	 * @param tabbedPropertySheetPage the tabbed property sheet page
	 * @param parent the parent
	 */
	public void createControls(final Composite parent,
			final TabbedPropertySheetPage tabbedPropertySheetPage) {
		super.createControls(parent, tabbedPropertySheetPage);
		final Composite composite = this.getWidgetFactory().createFlatFormComposite(parent);
		FormData data;
		
		// Show Name
		checkBoxShowName = this.getWidgetFactory().createButton(composite, "Show Name", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(0, 100);
		data.top = new FormAttachment(0, 0);
		checkBoxShowName.setLayoutData(data);
		
		showName = new SelectionListener() {
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e) {
				if((umlElement instanceof Relationship) && (umlElement instanceof  NamedElement)) {
					if ((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						((GraphNode)((GraphEdge)diagramElement).getContained().get(0)).setIsVisible(!((GraphNode)((GraphEdge)diagramElement).getContained().get(0)).isIsVisible());
						forceToSave();
					}		
				}
			}
		};
		
		checkBoxShowName.addSelectionListener(showName);
		
		// Show Condition
		checkBoxShowCondition = this.getWidgetFactory().createButton(composite, "Show Condition", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowName, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowCondition.setLayoutData(data);
		
		showCondition = new SelectionListener() {
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e) {
				if(umlElement instanceof Extend) {
					if ((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						Property property = diagramElement.getProperty(EdgeExtendHelper.KEY_EXTEND_CONDITION_DISPLAY);
						if (property != null) {
							if (property.getValue().equals(EdgeExtendHelper.IS_NOT_DISPLAYED)){
								addExtendConditionDisplay();
								property.setValue(EdgeExtendHelper.IS_DISPLAYED);
							} else {
								removeExtendConditionDisplay();
								property.setValue(EdgeExtendHelper.IS_NOT_DISPLAYED);
							}
						}
					}		
				}
			}
		};
		
		checkBoxShowCondition.addSelectionListener(showCondition);
				
		// Label of the section
		CLabel actorPresentationLabel = this.getWidgetFactory().createCLabel(composite, "Display Options:");
		data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(checkBoxShowName,
				-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(checkBoxShowName, 0, SWT.CENTER);
		actorPresentationLabel.setLayoutData(data);
	}

	/**
	 * Refresh the view othe multicplicity in the multicplicityCombo.
	 */
	@Override
	public void refresh() {
		if ((!checkBoxShowName.isDisposed())&&(!checkBoxShowCondition.isDisposed())) {
			// remove all listeners
			checkBoxShowName.removeSelectionListener(showName);
			checkBoxShowCondition.removeSelectionListener(showCondition);
			
			if ((diagramElement != null) && (((GraphElement)diagramElement).getSemanticModel() != null )){
				checkBoxShowName.setEnabled(true);
			
				if((umlElement instanceof Relationship) && (umlElement instanceof NamedElement)) {
					if (diagramElement instanceof GraphEdge){
						currentNameAppearance = ((GraphNode)((GraphEdge)diagramElement).getContained().get(0)).isIsVisible();
					}				
				}
				if(umlElement instanceof Extend) {
					if (diagramElement instanceof GraphEdge){
						checkBoxShowCondition.setEnabled(((Extend)umlElement).getCondition() != null);
						Property property = diagramElement.getProperty(EdgeExtendHelper.KEY_EXTEND_CONDITION_DISPLAY);
						if (property != null) {
							if (property.getValue().equals(EdgeExtendHelper.IS_DISPLAYED)) {
								currentExtendConditionAppearance = true;
							} else if (property.getValue().equals(EdgeExtendHelper.IS_NOT_DISPLAYED)) {
								currentExtendConditionAppearance = false;
							}
						} 
					}				
				}
				
			} else {
				checkBoxShowName.setEnabled(false);
				checkBoxShowCondition.setEnabled(false);
			}
			checkBoxShowName.setSelection(currentNameAppearance);
			checkBoxShowCondition.setSelection(currentExtendConditionAppearance);
			
			checkBoxShowName.addSelectionListener(showName);
			checkBoxShowCondition.addSelectionListener(showCondition);
		}		
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.cea.papyrus.core.ui.properties.tabbed.PropertyViewSection#dispose()
	 */
	@Override
	public void dispose(){
		super.dispose();
		if(checkBoxShowName!=null && !checkBoxShowName.isDisposed())
			checkBoxShowName.removeSelectionListener(showName);
		if(checkBoxShowCondition!=null && !checkBoxShowCondition.isDisposed())
			checkBoxShowCondition.removeSelectionListener(showCondition);
	}

	/**
	 * Adds the extend condition display.
	 */
	protected void addExtendConditionDisplay() {
		if (diagramElement != null) {		
			Extend extend = ((Extend)umlElement);
			
			// Create command
			Command command = new ExtendConditionDisplayCreateCommand(diagramElement, diagramElement.getContainer(), extend.getCondition());
	
			// Get command stack and execute command
			CommandStack stack = CommandStackUtils.getCommandStack();		
			Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
			stack.execute(command);
		}
	
	}

	/**
	 * Removes the extend condition display.
	 */
	protected void removeExtendConditionDisplay(){
		if(diagramElement != null) {
			// Create command
			CompoundCommand command = new CompoundCommand();
			
			MultiDiagramEditor mde = (MultiDiagramEditor)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
			
			Iterator graphElements = mde.getModelManager().lookForGraphElement(((Extend)umlElement).getCondition(), new ArrayList()).iterator();
			while(graphElements.hasNext()) {
				GraphElement ge = (GraphElement) graphElements.next();
				command.add(DiagramElementDeleteCommandFactory.eINSTANCE.createCommand(ge));
			}
	
			// Get command stack and execute command
			CommandStack stack = CommandStackUtils.getCommandStack();	
			Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
			stack.execute(command);
		}	
	}
}